package com.lanyou.cook.web;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.datadictionary.InterfaceRunResult;
import com.lanyou.cook.entity.domain.InterfaceExecutionResult;
import com.lanyou.cook.entity.domain.userManagement.User;
import com.lanyou.cook.repository.FieldSystemRepository;
import com.lanyou.cook.repository.KettleSlaveServerRepository;
import com.lanyou.cook.repository.SystemInterfaceRepository;
import com.lanyou.cook.repository.userManagement.UserRepository;
import com.lanyou.cook.service.KettleSlaveServerService;
import com.lanyou.cook.service.security.UserSessionService;
import com.lanyou.esb.datadictionary.IfType;
import com.lanyou.esb.entity.ClusterNode;
import com.lanyou.esb.repository.ClusterNodeRepository;
import com.lanyou.esb.repository.FtpLogRepository;
import com.lanyou.esb.repository.FtpRepository;
import com.lanyou.esb.repository.HttpRepository;
import com.lanyou.esb.repository.IfAlarmRepository;
import com.lanyou.esb.repository.QuantityControlRepository;
import com.lanyou.esb.web.RestAPI;

/**
 * 主界面管理相关业务控制层
 * @author 杨晨睿
 *
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/mainPage")
public class MainPageController {

	@Autowired
	private KettleSlaveServerService kettleSlaveServerService;
	@Autowired
	private UserRepository userRepository;
	@Autowired
	private FieldSystemRepository fieldSystemRepository;
	@Autowired
	private SystemInterfaceRepository systemInterfaceRepository;
	@PersistenceContext
	private EntityManager entityManager;
	@Autowired
	private KettleSlaveServerRepository kettleSlaveServerRepository;
	
	@Autowired
	private HttpRepository httpRepository;
	
	@Autowired
	private FtpRepository ftpRepository;
	
	@Autowired
	private ClusterNodeRepository clusterNodeRepository;
	@Autowired
	private IfAlarmRepository ifAlarmRepository;
	
	@Autowired
	private FtpLogRepository ftpLogRepository;
	
	@Autowired
	private UserSessionService userSessionService;
	
	@Autowired
	private QuantityControlRepository quantityControlRepository;
	
	private static FastDateFormat FASTDATEFORMAT_YYYYMMDDHHMMSS = FastDateFormat
			.getInstance(Constants.DATETIME_PATTERN_1);

	/**
	 * 获取管理员主界面相关数据
	 * @return 类型:String 管理员主界面数据
	 */
	@RequestMapping(value = "/search/getAdministratorInfo", produces = "application/json")
	public String getAdministratorInfo() {
		
		
		User user = userRepository.findByUserCode("admin");
		Date now = new Date();
		Calendar todayE = Calendar.getInstance();
		Calendar todayS = Calendar.getInstance();

		todayS.setTime(now);
		todayS.set(Calendar.HOUR_OF_DAY, 0);
		todayS.set(Calendar.MINUTE, 0);
		todayS.set(Calendar.SECOND, 0);

		todayE.setTime(now);

		String startDate = FASTDATEFORMAT_YYYYMMDDHHMMSS.format(todayS);
		String endDate = FASTDATEFORMAT_YYYYMMDDHHMMSS.format(todayE);
		BigInteger serviceAlarmCounts = null;
		List<Object> serviceAlarmCount = quantityControlRepository.findQuantityAlarmManagementTotalNum(user.getId(), "", "", startDate, endDate, "0", "");
		if(serviceAlarmCount != null && serviceAlarmCount.size() > 0){
			serviceAlarmCounts = (BigInteger)serviceAlarmCount.get(0);
		}
		
		Long unAuditCount = userRepository.countByRoleIsNull();
		Long systemCount = fieldSystemRepository.count();
		Long systemInterfaceCount = systemInterfaceRepository.count();
		/*Long httpInterfaceCount = httpRepository.count();*/
		Long httpInterfaceCount = httpRepository.countByIsEnable("1");
		/*Long ftpInterfaceCount = ftpRepository.count();*/
		Long ftpInterfaceCount = ftpRepository.countByIsEnable("1");
		long notRunNodeCount = kettleSlaveServerRepository.findAll()
					.stream().filter(  s -> !kettleSlaveServerService.isRunning(s.getId())  ).count();
		
		long notRunNodeEsbCount = 0;
		List<ClusterNode> clusterNodes = clusterNodeRepository.findAll();
		for (ClusterNode clusterNode : clusterNodes) {
			String flag = RestAPI.requestByGetMethod(clusterNode.getIpaddr(), clusterNode.getPort()+"" ,"NODE");
			if(StringUtils.equals(flag, "false")){
				notRunNodeEsbCount = notRunNodeEsbCount + 1;
			}
		}
		
		
		JsonObject jo = new JsonObject();
		jo.addProperty("serviceAlarmCounts", serviceAlarmCounts);
		jo.addProperty("unAuditCount", unAuditCount);
		jo.addProperty("systemCount", systemCount);
		jo.addProperty("systemInterfaceCount", systemInterfaceCount + httpInterfaceCount + ftpInterfaceCount);
		jo.addProperty("notRunNodeCount", notRunNodeCount + notRunNodeEsbCount);
		
		return jo.toString();
	}

	private static FastDateFormat fastDateFormat1 = FastDateFormat.getInstance(Constants.DATETIME_PATTERN_1);

	/**
	 * 获取其他用户主界面相关数据
	 * @return 类型:String 其他用户主界面数据
	 */
	@RequestMapping(value = "/search/getConsumerInfo", produces = "application/json")
	public String getConsumerInfo() throws ParseException {
		/* String str = getUsedSystemIds("admin1"); */
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -3);
		Date now = new Date();
		Date beginOfRunEndTime = DateUtils.truncate(calendar.getTime(),Calendar.DAY_OF_MONTH);
		
		//String b1 = fastDateFormat1.format(beginOfRunEndTime);
		
		Date endOfRunEndTime = DateUtils.ceiling(now, Calendar.DAY_OF_MONTH);
		
		//String b2 = fastDateFormat1.format(endOfRunEndTime);

		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Tuple> cq = cb.createTupleQuery();

		// 构建FROM和JOIN部分
		Root<InterfaceExecutionResult> rootInterfaceExecutionResult = cq.from(InterfaceExecutionResult.class);
		Collection<String> findFieldSystemIds = userSessionService.findFieldSystemIdsOfCurrentAuthenticatedUserCanManage();


		// 构建WHERE部分
		List<Predicate> predicatesList = new ArrayList<>();
		predicatesList.add(rootInterfaceExecutionResult.get("fieldSystemId").in(findFieldSystemIds));
		predicatesList.add(cb.equal(rootInterfaceExecutionResult.get("runResult"), InterfaceRunResult.Faild.ValueCode));
		predicatesList.add(cb.between(rootInterfaceExecutionResult.get("runEndTime"), beginOfRunEndTime, endOfRunEndTime));
		cq.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
		
		
		// 构建GROUP BY部分
		cq.groupBy(rootInterfaceExecutionResult.get("fieldName"), rootInterfaceExecutionResult.get("fieldSystemName"),
				rootInterfaceExecutionResult.get("interfaceName"));
		
		// 构建SELECT部分
		cq.multiselect(rootInterfaceExecutionResult.get("fieldSystemId").alias("fieldSystemId"),
				rootInterfaceExecutionResult.get("fieldName").alias("fieldName"),
				rootInterfaceExecutionResult.get("fieldSystemName").alias("fieldSystemName"),
				rootInterfaceExecutionResult.get("interfaceName").alias("interfaceName"),
				cb.count(rootInterfaceExecutionResult.get("id")).alias("faildInterfaceCount"));
		cq.orderBy(cb.desc(cb.count(rootInterfaceExecutionResult.get("id"))));
		
		// 执行查询
		TypedQuery<Tuple> q = entityManager.createQuery(cq);
		List<Tuple> queryResult = q.getResultList();

		JsonArray jsonDatas = new JsonArray();
		for (Tuple tuple : queryResult) {
			String fieldSystemId = tuple.get("fieldSystemId",String.class);
			String fieldName = tuple.get("fieldName", String.class);
			String fieldSystemName = tuple.get("fieldSystemName", String.class);
			String interfaceName = tuple.get("interfaceName", String.class);
			Long faildInterfaceCount = tuple.get("faildInterfaceCount", Long.class);

			if(faildInterfaceCount == 0){
				
			}else{
				JsonObject jo = new JsonObject();
				jo.addProperty("fieldSystemId", fieldSystemId);
				jo.addProperty("fieldName", fieldName);
				jo.addProperty("fieldSystemName", fieldSystemName);
				jo.addProperty("interfaceName", interfaceName);
				jo.addProperty("interfaceType", Constants.KETTLE);
				jo.addProperty("faildInterfaceCount", faildInterfaceCount);
				jo.addProperty("beginOfRunEndTime", fastDateFormat1.format(beginOfRunEndTime));
				jo.addProperty("endOfRunEndTime", fastDateFormat1.format(endOfRunEndTime));
				jsonDatas.add(jo);
			}
		}

		
		//ESB接口
		List<Object[]> httpErrorInterfaces = ifAlarmRepository.findHttpErrorInterfaces(userSessionService.getCurrentAuthenticatedUser().getId());
		for (Object[] object : httpErrorInterfaces) {
			JsonObject jo = new JsonObject();
			jo.addProperty("fieldSystemId", object[0] != null ? (String) object[0] : "");
			jo.addProperty("fieldName", object[1] != null ? (String) object[1] : "");
			jo.addProperty("fieldSystemName", object[2] != null ? (String) object[2] : "");
			jo.addProperty("interfaceName", object[3] != null ? (String) object[3] : "");
			String interfaceType = object[4] != null ? (String) object[4] : "";
			if(StringUtils.equals(interfaceType, IfType.WS.ValueCode)){
				jo.addProperty("interfaceType", Constants.WEBSERVICE);
			}else if(StringUtils.equals(interfaceType, IfType.REST.ValueCode)){
				jo.addProperty("interfaceType", Constants.REST);
			}else{
				
			}
			System.out.println(object[5]);
			long errorCount = object[5] != null ? ((BigDecimal) object[5]).longValue() : 0;
			if(errorCount == 0){
				break;
			}else{
				jo.addProperty("faildInterfaceCount", errorCount);
			}
			
			
			jsonDatas.add(jo);
		}
		
		
		// Ftp接口
		List<Object[]> ftpErrorInterfaces = ftpLogRepository
				.findFtpErrorInterfaces(userSessionService.getCurrentAuthenticatedUser().getId(), beginOfRunEndTime, endOfRunEndTime);
		for (Object[] object : ftpErrorInterfaces) {
			JsonObject jo = new JsonObject();
			jo.addProperty("fieldSystemId", object[0] != null ? (String) object[0] : "");
			jo.addProperty("fieldName", object[1] != null ? (String) object[1] : "");
			jo.addProperty("fieldSystemName", object[2] != null ? (String) object[2] : "");
			jo.addProperty("interfaceName", object[3] != null ? (String) object[3] : "");
			String interfaceType = object[4] != null ? (String) object[4] : "";
			if (StringUtils.equals(interfaceType, IfType.FTP.ValueCode)) {
				jo.addProperty("interfaceType", Constants.FTP);
			} else {

			}
			System.out.println(object[5]);
			long errorCount = object[5] != null ? ((BigInteger) object[5]).longValue() : 0;
			if (errorCount == 0) {
				break;
			} else {
				jo.addProperty("faildInterfaceCount", errorCount);
			}

			jsonDatas.add(jo);
		}
		JsonObject jsonResult = new JsonObject();
		if(jsonDatas.size() > 0){
			jsonResult.add("content", jsonDatas);
		}else{
			jsonResult.addProperty("backValue",true);
		}
		
		return jsonResult.toString();
	}
	
}
